#include "myqgraphicscene.h"
#include "myrectangleitem.h"
#include "mygraphicitem.h"
#include <QGraphicsSceneMouseEvent>
MyQGraphicScene::MyQGraphicScene(QObject *parent)
    : QGraphicsScene{parent}
    , m_bMousePressed(false)
    , m_PreMouseDirect(MouseMoveDirect::MouseMoveNone)
{}

void MyQGraphicScene::addNode(eSelectShape eType, QPointF point)
{
    if(eType == eSelectShape::eRectTangle)
    {
        MyRectangleItem* graphItem = new MyRectangleItem();
        m_curGrapViewItem = graphItem;
        graphItem->setPos(point.rx(), point.ry());
        this->addItem(graphItem);
    }
}

void MyQGraphicScene::setPos(QPointF point)
{
    m_curGrapViewItem->setPos(point.rx(), point.ry());
}

void MyQGraphicScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    QGraphicsScene::mousePressEvent(event);
    m_bMousePressed = true;
    if(m_eMode == Mode::InsertLine)
    {
        QList<QGraphicsItem *> selectedItems = this->selectedItems();
        if (!selectedItems.isEmpty())
        {
            for(QGraphicsItem * item : selectedItems)
            {
                QPointF scenePos = event->scenePos();
                MyGraphicItem * item1 = dynamic_cast<MyGraphicItem * >(item);
                item1->setFlag(QGraphicsItem::ItemIsMovable, false);
            }
        }

        lastPos = event->scenePos();
        m_startPos = event->scenePos();
        linePath.moveTo(m_startPos);
        points.push_back(event->scenePos());
        QPen pen(Qt::blue);
        pen.setWidth(2);

        pathItem = new QGraphicsPathItem(linePath);
        pathItem->setPen(pen);
        this->addItem(pathItem);
    }
}

void MyQGraphicScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
    QGraphicsScene::mouseMoveEvent(mouseEvent);
    if(!m_bMousePressed)
    {
        bool bChangeCur = false;
        QList<QGraphicsItem *> selectedItems = this->selectedItems();
        if (!selectedItems.isEmpty())
        {
            for(QGraphicsItem * item : selectedItems)
            {
                QPointF scenePos = mouseEvent->scenePos();
                MyGraphicItem * item1 = dynamic_cast<MyGraphicItem * >(item);
                if(item1->bChangeCur(scenePos, m_StartDirect))
                {
                    bChangeCur = true;
                    m_eMode = Mode::InsertLine;
                    emit sigChangeCur(bChangeCur);
                    return;
                }
            }
        }

        if(!bChangeCur)
        {
            m_eMode = Mode::InsertNone;
            emit sigChangeCur(bChangeCur);
        }
    }
    else
    {
        if (m_eMode == Mode::InsertLine) {

            QPointF delta = mouseEvent->scenePos() - lastPos;
            getEndDiection(mouseEvent->scenePos(), delta);
            switch (m_StartDirect) {
            case MouseMoveNorth:

                break;
            case MouseMoveSouth:

                break;
            case MouseMoveWest:

                break;
            case MouseMoveEast:

                break;
            default:
                break;
            }
        }
    }

    lastPos = mouseEvent->scenePos();

}

void MyQGraphicScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    points.clear();
    QGraphicsScene::mouseReleaseEvent(event);
    m_bMousePressed = false;
}

bool MyQGraphicScene::bPointOnLine(QLineF line, QPointF pointToCheck)
{
    QPointF startPoint = line.p1();
    QPointF endPoint = line.p2();

    // 向量AB和向量AC的叉积为0，则点C在直线AB上
    QPointF vectorAB = endPoint - startPoint;
    QPointF vectorAC = pointToCheck - startPoint;

    // 叉积的计算
    qreal crossProduct = vectorAB.x() * vectorAC.y() - vectorAB.y() * vectorAC.x();

    // 判断叉积是否接近于0，考虑浮点数误差
    bool isPointOnLine = qFuzzyCompare(crossProduct, 0.0);
    return isPointOnLine;
}

bool MyQGraphicScene::bChangeDirection(MouseMoveDirect direct)
{

    return true;

}

void MyQGraphicScene::changePoint(MouseMoveDirect direct, QPointF point, QPointF& point1)
{

}

MouseMoveDirect MyQGraphicScene::determineDirection(const QPointF &delta)
{
    if (delta.x() > 0) {
       return MouseMoveDirect::MouseMoveEast;
    } else if (delta.x() < 0) {
       return MouseMoveDirect::MouseMoveWest;
    }

    if (delta.y() > 0) {
       return MouseMoveDirect::MouseMoveSouth;
    } else if (delta.y() < 0) {
       return MouseMoveDirect::MouseMoveNorth;
    }
}

MouseMoveDirect MyQGraphicScene::getEndDiection(QPointF curPoint, QPointF& delta)
{
    MouseMoveDirect endDirection;
    MouseMoveDirect mouseDirection = determineDirection(delta);
    if(mouseDirection == MouseMoveDirect::MouseMoveEast)
    {
        qDebug() << "MouseMoveEast" ;
    }
    else if(mouseDirection == MouseMoveDirect::MouseMoveWest)
    {
        qDebug() << "MouseMoveWest" ;
    }
    else if(mouseDirection == MouseMoveDirect::MouseMoveNorth)
    {
        qDebug() << "MouseMoveNorth" ;
    }
    else if(mouseDirection == MouseMoveDirect::MouseMoveSouth)
    {
        qDebug() << "MouseMoveSouth" ;
    }

    int sy = m_startPos.ry();
    int sx = m_startPos.rx();
    int ex = curPoint.rx();
    int ey = curPoint.ry();
    int midx, midy;
    points.push_back(curPoint);
    switch (m_StartDirect) {
    case MouseMoveNorth:
        break;
    case MouseMoveSouth:
        linePath.clear();
        if(mouseDirection == MouseMoveDirect::MouseMoveEast)
        {
            linePath.moveTo(m_startPos);
            if(sy>ey)
            {
                if(sx>ex)
                {
                    midx = (sx+ex)>>1;
                    linePath.lineTo(midx,sy);
                    linePath.lineTo(midx,ey);
                    linePath.lineTo(ex,ey);
                }else{
                    linePath.lineTo(ex,sy);
                    linePath.lineTo(ex,ey);
                }

            }else{
                if(sx>ex){
                    linePath.lineTo(sx,ey);
                    linePath.lineTo(ex,ey);

                }else{
                    midy = (sy+ey)>>1;
                    linePath.lineTo(sx,midy);
                    linePath.lineTo(ex,midy);
                    linePath.lineTo(ex,ey);
                }
            }

            endDirection = MouseMoveDirect::MouseMoveWest;
        }
        else if(mouseDirection == MouseMoveDirect::MouseMoveWest)
        {
            linePath.clear();
            linePath.moveTo(m_startPos);
            if(sy>ey)
            {
                if(sx>ex)
                {
                    midx = (sx+ex)>>1;
                    linePath.lineTo(midx,sy);
                    linePath.lineTo(midx,ey);
                    linePath.lineTo(ex,ey);
                }else{
                    linePath.lineTo(ex,sy);
                    linePath.lineTo(ex,ey);
                }

            }else{
                if(sx>ex){
                    linePath.lineTo(sx,ey);
                    linePath.lineTo(ex,ey);
                }else{
                    midy = (sy+ey)>>1;
                    linePath.lineTo(sx,midy);
                    linePath.lineTo(ex,midy);
                    linePath.lineTo(ex,ey);
                }
            }
            endDirection = MouseMoveDirect::MouseMoveEast;
        }
        else if(mouseDirection == MouseMoveDirect::MouseMoveNorth)
        {
            linePath.clear();
            linePath.moveTo(m_startPos);
            if(sy>ey)
            {
                linePath.lineTo(ex,sy);
                linePath.lineTo(ex,ey);
            }else{
                linePath.lineTo(sx,ey);
                linePath.lineTo(ex,ey);
            }
            endDirection = MouseMoveDirect::MouseMoveSouth;
        }
        else if(mouseDirection == MouseMoveDirect::MouseMoveSouth)
        {
            linePath.clear();
            linePath.moveTo(m_startPos);
            if(sy>ey)
            {
                midx = (sx+ex)>>1;
                linePath.lineTo(midx,sy);
                linePath.lineTo(midx,ey);
                linePath.lineTo(ex,ey);
            }else{
                midy = (sy+ey)>>1;
                linePath.lineTo(sx,midy);
                linePath.lineTo(ex,midy);
                linePath.lineTo(ex,ey);
            }

            endDirection = MouseMoveDirect::MouseMoveNorth;
        }
        break;
    case MouseMoveWest:

        break;
    case MouseMoveEast:

        break;
    default:
        break;
    }

    pathItem->setPath(linePath);
    return endDirection;
}
